import { useEffect, useState, useRef } from 'react';

// Boid类型定义
export type Boid = {
  id: number;
  x: number;
  y: number;
  vx: number;
  vy: number;
  size: number;
  rotation: number;
};

// Boids系统配置参数
export type BoidsConfig = {
  // 场景边界
  width: number;
  height: number;
  // 水平线位置（用于鱼类限制）
  waterlineY?: number;
  // 是否为鸟类（true）或鱼类（false）
  isBird: boolean;
  // 初始数量
  count: number;
  // 最小/最大尺寸
  minSize: number;
  maxSize: number;
  // 最大速度
  maxSpeed: number;
  // 最大加速度
  maxForce: number;
  // 视野范围
  perceptionRadius: number;
  // 分离权重
  separationWeight: number;
  // 对齐权重
  alignmentWeight: number;
  // 凝聚权重
  cohesionWeight: number;
  // 边界回弹力
  boundaryWeight: number;
  // 随机游走权重
  wanderWeight: number;
};

// 默认鸟类配置
export const defaultBirdConfig: BoidsConfig = {
  width: 1000,
  height: 600,
  isBird: true,
  count: 8,
  minSize: 15,
  maxSize: 25,
  maxSpeed: 6,
  maxForce: 0.03,
  perceptionRadius: 120,
  separationWeight: 1.8,
  alignmentWeight: 1.2,
  cohesionWeight: 1.1,
  boundaryWeight: 0.6,
  wanderWeight: 0.2
};

// 默认鱼类配置
export const defaultFishConfig: BoidsConfig = {
  width: 1000,
  height: 600,
  waterlineY: 320,
  isBird: false,
  count: 10,
  minSize: 18,
  maxSize: 35,
  maxSpeed: 2.0,
  maxForce: 0.035,
  perceptionRadius: 100,
  separationWeight: 2.0,
  alignmentWeight: 1.1,
  cohesionWeight: 1.3,
  boundaryWeight: 0.9,
  wanderWeight: 0.3
};

// 向量操作辅助函数
const limit = (value: number, max: number): number => {
  return Math.abs(value) > max ? Math.sign(value) * max : value;
};

const distance = (x1: number, y1: number, x2: number, y2: number): number => {
  return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
};

// 主要的Boids系统Hook
export const useBoidsSystem = (config: BoidsConfig) => {
  const [boids, setBoids] = useState<Boid[]>([]);
  const configRef = useRef(config);
  const frameIdRef = useRef<number>(0);
  
  // 初始化Boids
  useEffect(() => {
    configRef.current = config;
    const initialBoids: Boid[] = [];
    
    for (let i = 0; i < config.count; i++) {
      let x, y;
      
      if (config.isBird) {
        // 鸟类在天空中初始化
        x = Math.random() * config.width;
        y = Math.random() * (config.waterlineY || config.height * 0.5);
      } else {
        // 鱼类在水中初始化
        x = Math.random() * config.width;
        y = (config.waterlineY || config.height * 0.5) + 
            Math.random() * (config.height - (config.waterlineY || config.height * 0.5));
      }
      
      initialBoids.push({
        id: i,
        x,
        y,
        vx: (Math.random() * 2 - 1) * config.maxSpeed * 0.5,
        vy: (Math.random() * 2 - 1) * config.maxSpeed * 0.5,
        size: config.minSize + Math.random() * (config.maxSize - config.minSize),
        rotation: 0
      });
    }
    
    setBoids(initialBoids);
    
    return () => {
      if (frameIdRef.current) {
        cancelAnimationFrame(frameIdRef.current);
      }
    };
  }, []);
  
  // 更新Boids位置和行为
  useEffect(() => {
    if (boids.length === 0) return;
    
    const updateBoids = () => {
      const { 
        width, height, waterlineY, isBird, maxSpeed, maxForce,
        perceptionRadius, separationWeight, alignmentWeight,
        cohesionWeight, boundaryWeight, wanderWeight
      } = configRef.current;
      
      setBoids(prevBoids => {
        // 性能优化：只在必要时更新
        return prevBoids.map(boid => {
          // 计算分离力
          let separationForceX = 0;
          let separationForceY = 0;
          let separationCount = 0;
          
          // 计算对齐力
          let alignmentForceX = 0;
          let alignmentForceY = 0;
          let alignmentCount = 0;
          
          // 计算凝聚力
          let cohesionForceX = 0;
          let cohesionForceY = 0;
          let cohesionCount = 0;
          
          // 检查其他boids的影响
          for (const other of prevBoids) {
            if (other.id === boid.id) continue;
            
            const dist = distance(boid.x, boid.y, other.x, other.y);
            
            if (dist < perceptionRadius) {
              // 分离：远离太近的邻居
              if (dist > 0) {
                const pushFactor = 1 / Math.max(dist, 0.1);
                separationForceX += (boid.x - other.x) * pushFactor;
                separationForceY += (boid.y - other.y) * pushFactor;
                separationCount++;
              }
              
              // 对齐：与邻居保持相似的速度
              alignmentForceX += other.vx;
              alignmentForceY += other.vy;
              alignmentCount++;
              
              // 凝聚：向邻居的平均位置移动
              cohesionForceX += other.x;
              cohesionForceY += other.y;
              cohesionCount++;
            }
          }
          
          // 计算最终的分离力
          if (separationCount > 0) {
            separationForceX /= separationCount;
            separationForceY /= separationCount;
            
            // 归一化并乘以权重
            const magnitude = Math.sqrt(separationForceX * separationForceX + separationForceY * separationForceY);
            if (magnitude > 0) {
              separationForceX = (separationForceX / magnitude) * maxSpeed * separationWeight;
              separationForceY = (separationForceY / magnitude) * maxSpeed * separationWeight;
            }
            
            // 限制最大力
            separationForceX = limit(separationForceX, maxForce);
            separationForceY = limit(separationForceY, maxForce);
          }
          
          // 计算最终的对齐力
          if (alignmentCount > 0) {
            alignmentForceX /= alignmentCount;
            alignmentForceY /= alignmentCount;
            
            // 归一化并乘以权重
            const magnitude = Math.sqrt(alignmentForceX * alignmentForceX + alignmentForceY * alignmentForceY);
            if (magnitude > 0) {
              alignmentForceX = (alignmentForceX / magnitude) * maxSpeed * alignmentWeight;
              alignmentForceY = (alignmentForceY / magnitude) * maxSpeed * alignmentWeight;
            }
            
            // 限制最大力
            alignmentForceX = limit(alignmentForceX - boid.vx, maxForce);
            alignmentForceY = limit(alignmentForceY - boid.vy, maxForce);
          }
          
          // 计算最终的凝聚力
          if (cohesionCount > 0) {
            cohesionForceX /= cohesionCount;
            cohesionForceY /= cohesionCount;
            
            // 计算指向中心的向量
            cohesionForceX = cohesionForceX - boid.x;
            cohesionForceY = cohesionForceY - boid.y;
            
            // 归一化并乘以权重
            const magnitude = Math.sqrt(cohesionForceX * cohesionForceX + cohesionForceY * cohesionForceY);
            if (magnitude > 0) {
              cohesionForceX = (cohesionForceX / magnitude) * maxSpeed * cohesionWeight;
              cohesionForceY = (cohesionForceY / magnitude) * maxSpeed * cohesionWeight;
            }
            
            // 限制最大力
            cohesionForceX = limit(cohesionForceX, maxForce);
            cohesionForceY = limit(cohesionForceY, maxForce);
          }
          
          // 边界力：防止离开屏幕
          let boundaryForceX = 0;
          let boundaryForceY = 0;
          
          const margin = 50;
          if (boid.x < margin) boundaryForceX = boundaryWeight;
          if (boid.x > width - margin) boundaryForceX = -boundaryWeight;
          if (boid.y < margin) boundaryForceY = boundaryWeight;
          if (boid.y > height - margin) boundaryForceY = -boundaryWeight;
          
          // 对鱼类增加水平线限制
          if (!isBird && waterlineY && boid.y < waterlineY + 20) {
            boundaryForceY = boundaryWeight * 2;
          }
          
          // 随机游走力：增加一些随机性
          const wanderForceX = (Math.random() * 2 - 1) * wanderWeight;
          const wanderForceY = (Math.random() * 2 - 1) * wanderWeight;
          
          // 计算总加速度
          let accelerationX = separationForceX + alignmentForceX + cohesionForceX + boundaryForceX + wanderForceX;
          let accelerationY = separationForceY + alignmentForceY + cohesionForceY + boundaryForceY + wanderForceY;
          
          // 更新速度
          let vx = boid.vx + accelerationX;
          let vy = boid.vy + accelerationY;
          
          // 限制最大速度
          const speed = Math.sqrt(vx * vx + vy * vy);
          if (speed > maxSpeed) {
            vx = (vx / speed) * maxSpeed;
            vy = (vy / speed) * maxSpeed;
          }
          
          // 计算旋转角度（基于速度方向）
          const rotation = Math.atan2(vy, vx) * (180 / Math.PI);
          
          // 更新位置
          let x = boid.x + vx;
          let y = boid.y + vy;
          
          // 边界处理（如果超出边界，从另一侧出现）
          if (x < -50) x = width + 50;
          if (x > width + 50) x = -50;
          
          // 鸟类和鱼类的垂直边界处理不同
          if (isBird) {
            if (y < -50) y = height * 0.4;
            if (y > height * 0.4) y = -50;
          } else {
            if (waterlineY) {
              if (y < waterlineY) y = waterlineY + 20;
              if (y > height + 50) y = waterlineY + 20;
            } else {
              if (y < height * 0.5) y = height * 0.5 + 20;
              if (y > height + 50) y = height * 0.5 + 20;
            }
          }
          
          return {
            ...boid,
            x,
            y,
            vx,
            vy,
            rotation: isBird ? rotation : rotation + 90 // 鱼类旋转角度调整
          };
        });
      });
      
      frameIdRef.current = requestAnimationFrame(updateBoids);
    };
    
    frameIdRef.current = requestAnimationFrame(updateBoids);
    
    return () => {
      if (frameIdRef.current) {
        cancelAnimationFrame(frameIdRef.current);
      }
    };
  }, [boids]);
  
  return boids;
};